home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 13 / Example 13.2 / app.cpp next >
Encoding:
C/C++ Source or Header  |  2006-08-01  |  7.9 KB  |  304 lines

  1. //////////////////////////////////////////////////////////////
  2. // Example 13.2: Play that funky music...                    //
  3. // Written by: C. Granberg, 2006                            //
  4. //////////////////////////////////////////////////////////////
  5.  
  6. #include <windows.h>
  7. #include <d3dx9.h>
  8. #include <vector>
  9. #include "debug.h"
  10. #include "mouse.h"
  11. #include "sound.h"
  12.  
  13. class APPLICATION
  14. {
  15.     public:
  16.         APPLICATION();
  17.         HRESULT Init(HINSTANCE hInstance, int width, int height, bool windowed);
  18.         HRESULT Update(float deltaTime);
  19.         HRESULT Render();
  20.         HRESULT Cleanup();
  21.         HRESULT Quit();
  22.  
  23.     private:
  24.         IDirect3DDevice9* m_pDevice; 
  25.         IDirect3DTexture9* m_pPlayTexture;
  26.         MOUSE m_mouse;
  27.         SOUND m_sound;
  28.         MP3 m_mp3Files[2];
  29.  
  30.         float m_volumes[2];
  31.         int m_playing;
  32.         LPD3DXSPRITE m_pSprite;
  33.         HWND m_mainWindow;
  34.         ID3DXFont *m_pFont;
  35. };
  36.  
  37. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
  38. {
  39.     APPLICATION app;
  40.  
  41.     if(FAILED(app.Init(hInstance, 800, 600, true)))
  42.         return 0;
  43.  
  44.     MSG msg;
  45.     memset(&msg, 0, sizeof(MSG));
  46.     int startTime = timeGetTime(); 
  47.  
  48.     while(msg.message != WM_QUIT)
  49.     {
  50.         if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  51.         {
  52.             ::TranslateMessage(&msg);
  53.             ::DispatchMessage(&msg);
  54.         }
  55.         else
  56.         {    
  57.             int t = timeGetTime();
  58.             float deltaTime = (t - startTime)*0.001f;
  59.  
  60.             app.Update(deltaTime);
  61.             app.Render();
  62.  
  63.             startTime = t;
  64.         }
  65.     }
  66.  
  67.     app.Cleanup();
  68.  
  69.     return msg.wParam;
  70. }
  71.  
  72. APPLICATION::APPLICATION()
  73. {
  74.     m_pDevice = NULL; 
  75.     m_mainWindow = 0;
  76.     m_pPlayTexture = NULL;
  77.     m_volumes[0] = 0.0f;
  78.     m_volumes[1] = 0.0f;
  79.     m_playing = -1;
  80.  
  81.     srand(GetTickCount());
  82. }
  83.  
  84. HRESULT APPLICATION::Init(HINSTANCE hInstance, int width, int height, bool windowed)
  85. {
  86.     debug.Print("Application initiated");
  87.  
  88.     //Create Window Class
  89.     WNDCLASS wc;
  90.     memset(&wc, 0, sizeof(WNDCLASS));
  91.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  92.     wc.lpfnWndProc   = (WNDPROC)::DefWindowProc; 
  93.     wc.hInstance     = hInstance;
  94.     wc.lpszClassName = "D3DWND";
  95.  
  96.     //Register Class and Create new Window
  97.     RegisterClass(&wc);
  98.     m_mainWindow = CreateWindow("D3DWND", "Example 13.2: Play that funky music...", WS_EX_TOPMOST, 0, 0, width, height, 0, 0, hInstance, 0); 
  99.     SetCursor(NULL);
  100.     ShowWindow(m_mainWindow, SW_SHOW);
  101.     UpdateWindow(m_mainWindow);
  102.  
  103.     //Create IDirect3D9 Interface
  104.     IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
  105.  
  106.     if(d3d9 == NULL)
  107.     {
  108.         debug.Print("Direct3DCreate9() - FAILED");
  109.         return E_FAIL;
  110.     }
  111.  
  112.     //Check that the Device supports what we need from it
  113.     D3DCAPS9 caps;
  114.     d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
  115.  
  116.     //Hardware Vertex Processing or not?
  117.     int vp = 0;
  118.     if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
  119.         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
  120.     else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  121.  
  122.     //Check vertex & pixelshader versions
  123.     if(caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
  124.     {
  125.         debug.Print("Warning - Your graphic card does not support vertex and pixelshaders version 2.0");
  126.     }
  127.  
  128.     //Set D3DPRESENT_PARAMETERS
  129.     D3DPRESENT_PARAMETERS d3dpp;
  130.     d3dpp.BackBufferWidth            = width;
  131.     d3dpp.BackBufferHeight           = height;
  132.     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
  133.     d3dpp.BackBufferCount            = 1;
  134.     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
  135.     d3dpp.MultiSampleQuality         = 0;
  136.     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
  137.     d3dpp.hDeviceWindow              = m_mainWindow;
  138.     d3dpp.Windowed                   = windowed;
  139.     d3dpp.EnableAutoDepthStencil     = true; 
  140.     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
  141.     d3dpp.Flags                      = 0;
  142.     d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
  143.     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
  144.  
  145.     //Create the IDirect3DDevice9
  146.     if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_mainWindow,
  147.                                  vp, &d3dpp, &m_pDevice)))
  148.     {
  149.         debug.Print("Failed to create IDirect3DDevice9");
  150.         return E_FAIL;
  151.     }
  152.  
  153.     //Release IDirect3D9 interface
  154.     d3d9->Release();
  155.  
  156.     D3DXCreateFont(m_pDevice, 18, 0, 0, 1, false,  
  157.                    DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
  158.                    DEFAULT_PITCH | FF_DONTCARE, "Arial", &m_pFont);
  159.  
  160.     //Set sampler state
  161.     for(int i=0;i<4;i++)
  162.     {
  163.         m_pDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  164.         m_pDevice->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  165.         m_pDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
  166.     }
  167.  
  168.     //Init mouse
  169.     m_mouse.InitMouse(m_pDevice, m_mainWindow);
  170.  
  171.     //Init Sound
  172.     m_sound.Init(m_mainWindow);
  173.  
  174.     //Init MP3 files
  175.     for(int i=0;i<2;i++)
  176.     {
  177.         m_mp3Files[i].Init();
  178.         if(i == 0)m_mp3Files[i].LoadSong(L"music/song1.mp3");
  179.         if(i == 1)m_mp3Files[i].LoadSong(L"music/song2.mp3");
  180.         m_mp3Files[i].Play();
  181.         m_mp3Files[i].SetVolume(m_volumes[i]);
  182.     }
  183.  
  184.     D3DXCreateTextureFromFile(m_pDevice, "textures/mp3Player.bmp", &m_pPlayTexture);
  185.     D3DXCreateSprite(m_pDevice, &m_pSprite);
  186.  
  187.     return S_OK;
  188. }
  189.  
  190. HRESULT APPLICATION::Update(float deltaTime)
  191. {
  192.     //Control camera
  193.     D3DXMATRIX  matWorld;
  194.     D3DXMatrixIdentity(&matWorld);
  195.     m_pDevice->SetTransform(D3DTS_WORLD, &matWorld);
  196.  
  197.     //Update mouse
  198.     m_mouse.Update();
  199.  
  200.     if(KEYDOWN(VK_ESCAPE))
  201.         Quit();
  202.  
  203.     //Update Mp3 Players
  204.     for(int i=0;i<2;i++)
  205.     {
  206.         if(m_playing == i)m_volumes[i] += deltaTime * 0.1f;
  207.         else
  208.         {
  209.             if((i == 0 && m_volumes[1] > 0.5f) || (i == 1 && m_volumes[0] > 0.5f))
  210.                 m_volumes[i] -= deltaTime * 0.1f;
  211.         }
  212.  
  213.         if(m_volumes[i] > 1.0f)m_volumes[i] = 1.0f;
  214.         if(m_volumes[i] < 0.0f)m_volumes[i] = 0.0f;
  215.  
  216.         m_mp3Files[i].SetVolume(m_volumes[i]);
  217.  
  218.         if(!m_mp3Files[i].IsPlaying())
  219.             m_mp3Files[i].Play();
  220.     }
  221.  
  222.     return S_OK;
  223. }    
  224.  
  225. HRESULT APPLICATION::Render()
  226. {
  227.     // Clear the viewport
  228.     m_pDevice->Clear(0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0L );
  229.  
  230.     // Begin the scene 
  231.     if(SUCCEEDED(m_pDevice->BeginScene()))
  232.     {
  233.         m_pSprite->Begin(0);
  234.         
  235.         RECT playRects[] = {{100, 250, 200, 350}, {500, 250, 600, 350}};        
  236.         RECT playSrc[] = {{0, 0, 100, 100}, {0, 100, 100, 200}};
  237.         RECT volSrc[] = {{100, 0, 150, 140}, {150, 0, 200, 140}};
  238.  
  239.         for(int i=0;i<2;i++)
  240.         {
  241.             int src = 0;
  242.             if(m_mouse.Over(playRects[i]))src = 1;
  243.             
  244.             //Play Button
  245.             m_pSprite->Draw(m_pPlayTexture, &playSrc[src], NULL, &D3DXVECTOR3(playRects[i].left, playRects[i].top, 0.0f), 0xffffffff);
  246.             if(m_mouse.PressInRect(playRects[i]))
  247.             {
  248.                 m_mouse.DisableInput(300);
  249.                 m_playing = i;
  250.             }
  251.  
  252.             //Volume meter
  253.             int v = 140 - 140 * m_volumes[i];
  254.             RECT a = {volSrc[0].left, volSrc[0].top + v, volSrc[0].right, volSrc[0].bottom};
  255.             RECT b = {volSrc[1].left, volSrc[1].top, volSrc[1].right, volSrc[1].top + v};
  256.             m_pSprite->Draw(m_pPlayTexture, &a, NULL, &D3DXVECTOR3(playRects[i].left + 110, playRects[i].top - 20 + v, 0.0f), 0xffffffff);            
  257.             m_pSprite->Draw(m_pPlayTexture, &b, NULL, &D3DXVECTOR3(playRects[i].left + 110, playRects[i].top - 20, 0.0f), 0xffffffff);
  258.         }
  259.  
  260.  
  261.         m_pSprite->End();
  262.  
  263.  
  264.         RECT r[] = {{0, 568, 800, 600}, {4, 570, 800, 600}};
  265.         m_pFont->DrawText(NULL, "Music composed and produced by Paul Houseman (www.paulhouseman.com)", -1, &r[0], DT_CENTER | DT_TOP | DT_NOCLIP, 0xffAAAAAA);
  266.         m_pFont->DrawText(NULL, "Music composed and produced by Paul Houseman (www.paulhouseman.com)", -1, &r[1], DT_CENTER | DT_TOP | DT_NOCLIP, 0xff444444);
  267.  
  268.         //Draw mouse
  269.         m_mouse.Paint();
  270.  
  271.         // End the scene.
  272.         m_pDevice->EndScene();
  273.         m_pDevice->Present(0, 0, 0, 0);
  274.     }
  275.  
  276.     return S_OK;
  277. }
  278.  
  279. HRESULT APPLICATION::Cleanup()
  280. {
  281.     try
  282.     {
  283.         m_mp3Files[0].Release();
  284.         m_mp3Files[1].Release();
  285.  
  286.         if(m_pSprite)m_pSprite->Release();
  287.         if(m_pPlayTexture)m_pPlayTexture->Release();
  288.  
  289.         m_pFont->Release();
  290.         m_pDevice->Release();
  291.  
  292.         debug.Print("Application terminated");
  293.     }
  294.     catch(...){}
  295.  
  296.     return S_OK;
  297. }
  298.  
  299. HRESULT APPLICATION::Quit()
  300. {
  301.     ::DestroyWindow(m_mainWindow);
  302.     ::PostQuitMessage(0);
  303.     return S_OK;
  304. }